package com.mini.service;

import com.alibaba.fastjson.JSON;
import com.mini.config.BusinessException;
import com.mini.constant.RedisKeyConst;
import com.mini.model.*;
import com.mini.repository.*;
import com.mini.req.RequirementPlanFormReq;
import com.mini.req.RequirementPlanSaveReq;
import com.mini.req.RequirementPlanTableReq;
import com.mini.res.*;
import com.mini.util.SnowFlake;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 项目名称：traditional-business
 * 类 名 称：BusinessRequirementPlanService
 * 类 描 述：需求规划业务
 * 创建时间：2020/12/15 下午7:56
 * 创 建 人：zhanghuiying
 */
@Slf4j
@Service
public class BusinessRequirementPlanService extends BaseService {

    @Autowired
    private BusinessRequirementPlanBaseRepository businessRequirementPlanBaseRepository;
    @Autowired
    private BusinessRequirementPlanFormRepository businessRequirementPlanFormRepository;
    @Autowired
    private BusinessRequirementPlanTableRepository businessRequirementPlanTableRepository;
    @Autowired
    private BusinessRequirementPlanTableFormRepository businessRequirementPlanTableFormRepository;
    @Autowired
    private BusinessRequirementPlanBaseTableFormRepository businessRequirementPlanBaseTableFormRepository;
    @Autowired
    private BusinessRequirementPlanNeedRepository businessRequirementPlanNeedRepository;
    @Autowired
    private CooperativeRepository cooperativeRepository;
    @Autowired
    private CooperativeService cooperativeService;
    @Autowired
    protected RedisTemplate redisTemplate;
    @Autowired
    private CooperativeAndPlanLogRecordService operationRecordService;

    /*
     * @name:copyRequirementPlan
     * @description: 复制昨日需求规划
     * @return: boolean
     * @date: 2020/12/16 下午1:46
     * @auther: zhy
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean copyRequirementPlan(String token, Long quantumArmyGroupId, Date planDate) {
        StopWatch sw = new StopWatch();
        sw.start();
        Long userId = miniAdminService.getLoginUserId(token);
        if (userId == null) {
            throw new BusinessException("token解析失败,请稍后重试或重新登陆！");
        }
//        Long userId = 2036L;
        BusinessRequirementPlanBaseBean businessRequirementPlanBaseBean = businessRequirementPlanBaseRepository.findByQuantumArmyGroupIdAndPlanDateAndBaseDelete(quantumArmyGroupId, planDate, 0);
        if (Objects.isNull(businessRequirementPlanBaseBean)) {
            throw new BusinessException("该量子军团昨日数据不存在！");
        }
        log.info("获得量子军团昨日数据{}", businessRequirementPlanBaseBean);
        BusinessRequirementPlanBaseBean requirementPlanBaseBean = new BusinessRequirementPlanBaseBean();
        BeanUtils.copyProperties(businessRequirementPlanBaseBean, requirementPlanBaseBean);
//        判断该量子军团当天数据是否存在
        Calendar c = Calendar.getInstance();
        c.setTime(planDate);
        int day1 = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day1 + 1);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = "";
        format = dateFormat.format(c.getTime());
        try {
//          加分布式锁更新
            if (tryLock("updateRequirementPlan:" + quantumArmyGroupId.toString() + format)) {
                if (redisTemplate.hasKey(RedisKeyConst.getRequirementPlan(quantumArmyGroupId, format))) {
                    redisTemplate.delete(RedisKeyConst.getRequirementPlan(quantumArmyGroupId, format));
                    log.info("删除redis中当天需求规划信息成功，quantumArmyGroupId：{},planDate{}", quantumArmyGroupId, format);
                }
//              封装base表数据
                requirementPlanBaseBean.setCreateTime(new Date());
                requirementPlanBaseBean.setCreateUserId(userId);
                requirementPlanBaseBean.setUpdateTime(new Date());
                requirementPlanBaseBean.setPlanDate(c.getTime());
                BusinessRequirementPlanBaseBean lastBasebean = businessRequirementPlanBaseRepository.findByQuantumArmyGroupIdAndPlanDateAndBaseDelete(quantumArmyGroupId, c.getTime(), 0);
                if (lastBasebean != null) {
                    Long oldId = lastBasebean.getId();
                    Long oldQuantumArmyGroupId = lastBasebean.getQuantumArmyGroupId();
                    Date EndTime = lastBasebean.getEndTime();
                    Integer oldCardCount = lastBasebean.getCardCount();
                    String receivingResidue = lastBasebean.makeReceivingResidue();
                    String pattern = lastBasebean.makePattern();
                    // 保存操作记录
                    try {
                        asyncTaskManager.getExecutor().submit(new Runnable() {
                            @Override
                            public void run() {
                                operationRecordService.addRequirementPlanBaseLog(oldId, oldQuantumArmyGroupId, EndTime, oldCardCount, receivingResidue, pattern, requirementPlanBaseBean);
                                log.info("需求规划 添加基础信息 日志记录");
                            }
                        });
                    } catch (Exception e) {
                        log.error("需求规划 添加基础信息 日志记录异常", e);
                    }
                    requirementPlanBaseBean.setId(lastBasebean.getId());
//                  删除当天表内容信息
                    BusinessRequirementPlanTableBean planTableBean = new BusinessRequirementPlanTableBean();
                    planTableBean.setBaseId(lastBasebean.getId());
                    planTableBean.setTableDelete(0);
                    Example<BusinessRequirementPlanTableBean> example = Example.of(planTableBean);
                    List<BusinessRequirementPlanTableBean> tableBeans = businessRequirementPlanTableRepository.findAll(example);
                    if (!CollectionUtils.isEmpty(tableBeans)) {
                        tableBeans.stream()
                                .forEach(t -> t.setTableDelete(1));
                        businessRequirementPlanTableRepository.save(tableBeans);
                        List<Long> tableId = tableBeans.stream()
                                .map(BusinessRequirementPlanTableBean::getId)
                                .collect(Collectors.toList());
                        businessRequirementPlanFormRepository.updateByTableIds(tableId);
                        businessRequirementPlanNeedRepository.updateByTableIds(tableId);
                        log.info("删除库中旧数据成功，tableIds：{}", tableId);
                    }
                    // 保存操作记录
                    try {
                        asyncTaskManager.getExecutor().submit(new Runnable() {
                            @Override
                            public void run() {
                                for (BusinessRequirementPlanTableBean t :
                                        tableBeans) {
                                    List<BusinessRequirementPlanFormBean> form = businessRequirementPlanFormRepository.findByTableIdAndFormDelete(t.getId(), 0);
                                    operationRecordService.deleteRequirementPlanBaseLog(userId, quantumArmyGroupId.longValue(), lastBasebean.getPlanDate(), form, t, token);
                                }
                                log.info("需求规划 删除某个项目的表信息 日志记录");
                            }
                        });
                    } catch (Exception e) {
                        log.error("需求规划 删除某个项目的表信息 日志记录异常", e);
                    }
                } else {
                    long baseId = SnowFlake.nextId();
                    requirementPlanBaseBean.setId(baseId);
                    // 保存操作记录
                    try {
                        asyncTaskManager.getExecutor().submit(new Runnable() {
                            @Override
                            public void run() {
                                operationRecordService.addRequirementPlanBaseLog(null, null, null, null, null, null, requirementPlanBaseBean);
                                log.info("需求规划 添加基础信息 日志记录");
                            }
                        });
                    } catch (Exception e) {
                        log.error("需求规划 添加基础信息 日志记录异常", e);
                    }
                }
                businessRequirementPlanBaseRepository.save(requirementPlanBaseBean);
                log.info("已复制昨日的基础数据入库，数据id{}", requirementPlanBaseBean.getId());

//              拿到昨日该量子军团的所有需求规划内容信息
                List<BusinessRequirementPlanTableAndForm> businessRequirementPlanTableAndForms = businessRequirementPlanTableFormRepository.findByBaseIdInTableAndForm(businessRequirementPlanBaseBean.getId());
                if (CollectionUtils.isEmpty(businessRequirementPlanTableAndForms)) {
//                  需求规划不存在，只复制基础信息
                    return true;
                }
//              按照table分组
                Map<Long, List<BusinessRequirementPlanTableAndForm>> mapTask = businessRequirementPlanTableAndForms.stream().sorted(Comparator.comparing((b) -> b.getId())).collect(Collectors.groupingBy((a) -> a.getTableId()));
                List<RequirementPlanTableReq> requirementPlanTableReqs = new ArrayList<>();
                for (Map.Entry<Long, List<BusinessRequirementPlanTableAndForm>> entry : mapTask.entrySet()) {
                    RequirementPlanTableReq requirementPlanTableReq = new RequirementPlanTableReq();
                    BeanUtils.copyProperties(entry.getValue().get(0), requirementPlanTableReq);

                    List<RequirementPlanFormReq> requirementPlanFormReqs = new ArrayList<>();
//                  按照neeid分组
                    Map<Long, List<BusinessRequirementPlanTableAndForm>> byNeed = entry.getValue().stream().sorted(Comparator.comparing((b) -> b.getId())).collect(Collectors.groupingBy((a) -> a.getNeedId()));
                    for (Map.Entry<Long, List<BusinessRequirementPlanTableAndForm>> one :
                            byNeed.entrySet()) {
                        List<String> provinces = new ArrayList<>();
                        Integer needCount = one.getValue().get(0).getNeedCount();
                        for (BusinessRequirementPlanTableAndForm p :
                                one.getValue()) {
//                          获取省份code
                            provinces.add(p.getProvince());
                        }
                        RequirementPlanFormReq requirementPlanFormReq = new RequirementPlanFormReq();
                        BeanUtils.copyProperties(one.getValue().get(0), requirementPlanFormReq);
                        requirementPlanFormReq.setNeedCount(needCount);
                        requirementPlanFormReq.setProvince(String.join(",", provinces));
                        requirementPlanFormReqs.add(requirementPlanFormReq);
                    }
                    requirementPlanTableReq.setRequirementPlanFormRes(requirementPlanFormReqs);
                    requirementPlanTableReqs.add(requirementPlanTableReq);
                }
                saveTableAndForm(userId, requirementPlanBaseBean.getId(), requirementPlanBaseBean.getPlanDate(), requirementPlanTableReqs, quantumArmyGroupId, token);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        } finally {
            releaseLockKey("updateRequirementPlan:" + quantumArmyGroupId.toString() + businessRequirementPlanBaseBean.getPlanDate().toString());
        }
        sw.stop();
        log.info("方法耗时：{}", sw.getTotalTimeMillis());
        return true;
    }

    /*
     * @name:deleteRequirementPlan
     * @description: 删除需求规划列表
     * @return:boolean
     * @date: 2020/12/16 下午1:52
     * @auther: zhy
     *
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteRequirementPlan(String token, Long userId, Long tableId, Long quantumArmyGroupId, Date planDate) {
        BusinessRequirementPlanTableBean tableBean = businessRequirementPlanTableRepository.findOne(tableId);
        if (Objects.isNull(tableBean)) {
            throw new BusinessException("要删除的规划表不存在！");
        }

        tableBean.setTableDelete(1);
        tableBean.setUpdateUserId(userId);
        List<BusinessRequirementPlanFormBean> businessRequirementPlanFormBeans = businessRequirementPlanFormRepository.findByTableIdAndFormDelete(tableId, 0);
        businessRequirementPlanFormBeans.stream()
                .forEach(f -> {
                    f.setFormDelete(1);
                    f.setUpdateUserId(userId);
                });
        List<BusinessRequirementPlanNeedBean> businessRequirementPlanNeedBeans = businessRequirementPlanNeedRepository.findByTableIdAndNeedDelete(tableId, 0);
        businessRequirementPlanNeedBeans.stream()
                .forEach(n -> {
                    n.setNeedDelete(1);
                    n.setUpdateUserId(userId);
                });
        businessRequirementPlanTableRepository.save(tableBean);
        businessRequirementPlanFormRepository.save(businessRequirementPlanFormBeans);
        businessRequirementPlanNeedRepository.save(businessRequirementPlanNeedBeans);
        log.info("删除需求规划成功，表信息{}", tableBean);
        // 保存操作记录
        try {
            asyncTaskManager.getExecutor().submit(new Runnable() {
                @Override
                public void run() {
                    operationRecordService.deleteRequirementPlanBaseLog(userId, quantumArmyGroupId, planDate, businessRequirementPlanFormBeans, tableBean, token);
                    log.info("需求规划 删除某个项目的表信息 日志记录");
                }
            });
        } catch (Exception e) {
            log.error("需求规划 删除某个项目的表信息 日志记录异常", e);
        }
        return true;
    }

    /*
     * @name:  queryRequirementPlanCount
     * @description: 查询需求规划内容信息
     * @return: RequirementPlanFindReq
     * @date: 2020/12/16 下午2:05
     * @auther: zhy
     *
     */
    public RequirementPlanFindRes queryRequirementPlanCount(String token, Long quantumArmyGroupId, String planDate) {
        StopWatch sw = new StopWatch();
        sw.start();
        Long userId = miniAdminService.getLoginUserId(token);
        if (userId == null) {
            throw new BusinessException("token解析失败,请稍后重试或重新登陆！");
        }
//        Long userId =2036L;
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = formatter.parse(planDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        if (redisTemplate.hasKey(RedisKeyConst.getRequirementPlan(quantumArmyGroupId, planDate))) {
            log.info("从redis中获取需求规划信息，quantumArmyGroupId{},planDate{}", quantumArmyGroupId, planDate);
            return JSON.parseObject(JSON.toJSONString(redisTemplate.opsForValue().get(RedisKeyConst.getRequirementPlan(quantumArmyGroupId, planDate))), RequirementPlanFindRes.class);
        }
//        获取该量子军团需求分配的基础信息
        BusinessRequirementPlanBaseBean requirementPlanBaseBean = businessRequirementPlanBaseRepository.findByQuantumArmyGroupIdAndPlanDateAndBaseDelete(quantumArmyGroupId, date, 0);
        if (Objects.isNull(requirementPlanBaseBean)) {
            return null;
        }
        RequirementPlanFindRes requirementPlanFindRes = new RequirementPlanFindRes();
        BeanUtils.copyProperties(requirementPlanBaseBean, requirementPlanFindRes);
        requirementPlanFindRes.setBaseId(requirementPlanBaseBean.getId());
        log.info("获取该量子军团需求分配的基础信息内容{}", requirementPlanBaseBean);

//        获取该量子军团该天的所有数据信息
        List<BusinessRequirementPlanTableAndForm> businessRequirementPlanTableAndForms = businessRequirementPlanTableFormRepository.findByBaseIdInTableAndForm(requirementPlanBaseBean.getId());
        if (CollectionUtils.isEmpty(businessRequirementPlanTableAndForms)) {
            return requirementPlanFindRes;
        }
        log.info("获取该量子军团该天的所有数据信息内容{}", businessRequirementPlanTableAndForms);

//      获取项目省份渠道名称列表
        Map<Integer, String> projectMap = cooperativeService.getProjectMap(token);
        Map<String, String> channelMap = cooperativeService.getChannelMap(token);
        Map<String, String> provinceMap = cooperativeService.getProvinceMap(token);

        List<RequirementPlanTableRes> requirementPlanTableResList = new ArrayList<>();
//        按照项目不同分组
        Map<Long, List<BusinessRequirementPlanTableAndForm>> allTable = businessRequirementPlanTableAndForms.stream().sorted(Comparator.comparing((b) -> b.getId())).collect(Collectors.groupingBy((a) -> a.getTableId()));
        for (Map.Entry<Long, List<BusinessRequirementPlanTableAndForm>> oneTable :
                allTable.entrySet()) {
            Long tId = oneTable.getValue().get(0).getTableId();
//          拿到该项目表的所有规划内容信息
            List<BusinessRequirementPlanTableAndForm> formList = oneTable.getValue();
            log.info("拿到该项目表的所有规划内容信息{}", formList);
//            根据单元格标识进行分组
            Map<Long, List<BusinessRequirementPlanTableAndForm>> mapTask = formList.stream().sorted(Comparator.comparing((b) -> b.getId())).collect(Collectors.groupingBy((a) -> a.getNeedId()));
//            map用于存放渠道，和该渠道下的内容信息
            Map<String, List<RequirementPlanCellRes>> formMap = new HashMap<>();
            for (Map.Entry<Long, List<BusinessRequirementPlanTableAndForm>> entry : mapTask.entrySet()) {

                List<String> provinceName = new ArrayList<>();
                List<String> province = new ArrayList<>();
                Integer allotCount = 0;
                for (BusinessRequirementPlanTableAndForm p :
                        entry.getValue()) {
//                  获取省份名称
                    provinceName.add(provinceMap.get(p.getProvince()));
                    province.add(p.getProvince());
//                  计算已分配量
                    allotCount += p.getAllotCount();
                }
                BusinessRequirementPlanTableAndForm tf = entry.getValue().get(0);

                RequirementPlanCellRes requirementPlanCellRes = new RequirementPlanCellRes();
                BeanUtils.copyProperties(tf, requirementPlanCellRes);
                requirementPlanCellRes.setProvinceName(String.join(",", provinceName));
                requirementPlanCellRes.setProvince(String.join(",", province));
                requirementPlanCellRes.setNeedId(tf.getNeedId());
                requirementPlanCellRes.setAllotCount(allotCount);
//                获取渠道下的内容信息
                if (!formMap.containsKey(tf.getChannelCode())) {
                    List<RequirementPlanCellRes> requirementPlanCellResList = new ArrayList<>();
                    requirementPlanCellResList.add(requirementPlanCellRes);
                    formMap.put(tf.getChannelCode(), requirementPlanCellResList);
                } else {
                    List<RequirementPlanCellRes> requirementPlanCellResList = formMap.get(tf.getChannelCode());
                    requirementPlanCellResList.add(requirementPlanCellRes);
                    formMap.put(tf.getChannelCode(), requirementPlanCellResList);
                }
            }
            log.info("拿到渠道，和该渠道下的内容信息{}", formMap);
            List<RequirementPlanFormRes> requirementPlanFormResList = new ArrayList<>();
            for (Map.Entry<String, List<RequirementPlanCellRes>> entry : formMap.entrySet()) {
                RequirementPlanFormRes requirementPlanFormRes = new RequirementPlanFormRes();
//                获取渠道名称
                String channelName = channelMap.get(entry.getKey());
                requirementPlanFormRes.setChannel(channelName);
                requirementPlanFormRes.setChannelCode(entry.getKey());
                Collections.reverse(entry.getValue());
                requirementPlanFormRes.setRequirementPlanCellRes(entry.getValue());
                requirementPlanFormResList.add(requirementPlanFormRes);
            }
            log.info("封装渠道下内容信息成功{}", requirementPlanFormResList);
            RequirementPlanTableRes requirementPlanTableRes = new RequirementPlanTableRes();
            requirementPlanTableRes.setTableId(tId);
//            获取项目名称
            String projectName = projectMap.get(formList.get(0).getProjectId());
            requirementPlanTableRes.setProjectName(projectName);
            requirementPlanTableRes.setProjectId(formList.get(0).getProjectId());
            Collections.reverse(requirementPlanFormResList);
            requirementPlanTableRes.setRequirementPlanFormRes(requirementPlanFormResList);
            requirementPlanTableResList.add(requirementPlanTableRes);
            log.info("封装需求规划列表tableId：{}成功,内容", tId, requirementPlanTableRes);
        }
        requirementPlanFindRes.setRequirementPlanTableRes(requirementPlanTableResList);
        redisTemplate.opsForValue().set(RedisKeyConst.getRequirementPlan(quantumArmyGroupId, planDate), requirementPlanFindRes, 6, TimeUnit.HOURS);
        log.info("需求规划信息存入redis，quantumArmyGroupId{},planDate{}", quantumArmyGroupId, planDate);
        sw.stop();
        log.info("方法耗时：{}", sw.getTotalTimeMillis());
        return requirementPlanFindRes;
    }

    /*
     * @name:  saveRequirementPlan
     * @description: 保存需求规划
     * @return: boolean
     * @date: 2020/12/16 下午6:31
     * @auther: zhy
     *
     */
    @Transactional
    public Boolean saveRequirementPlan(String token, RequirementPlanSaveReq requirementPlanSaveReq) {
        StopWatch sw = new StopWatch();
        sw.start();
        Long userId = miniAdminService.getLoginUserId(token);
        if (userId == null) {
            throw new BusinessException("token解析失败,请稍后重试或重新登陆！");
        }
//        Long userId =2036L;
        try {
//          加分布式锁更新
            if (tryLock("updateRequirementPlan:" + requirementPlanSaveReq.getQuantumArmyGroupId().toString() + requirementPlanSaveReq.getPlanDate().toString())) {
//              删除redis中的信息
                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                String planDate = formatter.format(requirementPlanSaveReq.getPlanDate());
                if (redisTemplate.hasKey(RedisKeyConst.getRequirementPlan(requirementPlanSaveReq.getQuantumArmyGroupId(), planDate))) {
                    redisTemplate.delete(RedisKeyConst.getRequirementPlan(requirementPlanSaveReq.getQuantumArmyGroupId(), planDate));
                    log.info("已删除redis中的信息");
                }
                if (!CollectionUtils.isEmpty(requirementPlanSaveReq.getTableIds())) {
                    for (Long tableId :
                            requirementPlanSaveReq.getTableIds()) {
                        deleteRequirementPlan(token, userId, tableId, requirementPlanSaveReq.getQuantumArmyGroupId(), requirementPlanSaveReq.getPlanDate());
                    }
                }
//              保存基础信息
                BusinessRequirementPlanBaseBean businessRequirementPlanBaseBean = saveBase(userId, requirementPlanSaveReq);
//              保存表和表内容信息
                saveTableAndForm(userId, businessRequirementPlanBaseBean.getId(), businessRequirementPlanBaseBean.getPlanDate(), requirementPlanSaveReq.getRequirementPlanTableReqList(), requirementPlanSaveReq.getQuantumArmyGroupId(), token);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        } finally {
            releaseLockKey("updateRequirementPlan:" + requirementPlanSaveReq.getQuantumArmyGroupId().toString() + requirementPlanSaveReq.getPlanDate().toString());
        }
        sw.stop();
        log.info("方法耗时：{}", sw.getTotalTimeMillis());
        return true;
    }

    /*
     * @name:
     * @description: 保存或更新需求规划基础信息
     * @param RequirementPlanSaveReq
     * @date: 2020/12/19 下午4:00
     * @auther: zhy
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.SUPPORTS)
    public BusinessRequirementPlanBaseBean saveBase(Long userId, RequirementPlanSaveReq requirementPlanSaveReq) {
        BusinessRequirementPlanBaseBean businessRequirementPlanBaseBean = new BusinessRequirementPlanBaseBean();

        if (Objects.isNull(requirementPlanSaveReq.getBaseId())) {
            // 如果id不存在，新增一条基础记录
            BusinessRequirementPlanBaseBean findbaseBean = businessRequirementPlanBaseRepository.findByQuantumArmyGroupIdAndPlanDateAndBaseDelete(requirementPlanSaveReq.getQuantumArmyGroupId(), requirementPlanSaveReq.getPlanDate(), 0);
            if (findbaseBean != null) {
                throw new BusinessException("该量子军团该天数据已经存在,请刷新尝试!");
            }
            BeanUtils.copyProperties(requirementPlanSaveReq, businessRequirementPlanBaseBean);
            Long baseId = SnowFlake.nextId();
            businessRequirementPlanBaseBean.setId(baseId);
            businessRequirementPlanBaseBean.setCreateUserId(userId);
            businessRequirementPlanBaseBean.setBaseDelete(0);
            // 保存操作记录
            try {
                asyncTaskManager.getExecutor().submit(new Runnable() {
                    @Override
                    public void run() {
                        operationRecordService.addRequirementPlanBaseLog(null, null, null, null, null, null, businessRequirementPlanBaseBean);
                        log.info("需求规划 更新基础信息 日志记录");
                    }
                });
            } catch (Exception e) {
                log.error("需求规划 更新基础信息 日志记录异常", e);
            }
        } else {// 如果id存在，更新基础记录
            BusinessRequirementPlanBaseBean old = businessRequirementPlanBaseRepository.findOne(requirementPlanSaveReq.getBaseId());
            Long oldId = old.getId();
            Long oldQuantumArmyGroupId = old.getQuantumArmyGroupId();
            Date EndTime = old.getEndTime();
            Integer oldCardCount = old.getCardCount();
            String receivingResidue = old.makeReceivingResidue();
            String pattern = old.makePattern();
            if (old == null) {
                throw new BusinessException("基础信息不存在!");
            }
            BeanUtils.copyProperties(requirementPlanSaveReq, businessRequirementPlanBaseBean);
            businessRequirementPlanBaseBean.setUpdateUserId(userId);
            businessRequirementPlanBaseBean.setUpdateTime(new Date());
            businessRequirementPlanBaseBean.setId(old.getId());
            businessRequirementPlanBaseBean.setCreateUserId(userId);
            businessRequirementPlanBaseBean.setCreateTime(new Date());
            businessRequirementPlanBaseBean.setBaseDelete(0);

            // 保存操作记录
            try {
                asyncTaskManager.getExecutor().submit(new Runnable() {
                    @Override
                    public void run() {
                        operationRecordService.addRequirementPlanBaseLog(oldId, oldQuantumArmyGroupId, EndTime, oldCardCount, receivingResidue, pattern, businessRequirementPlanBaseBean);
                        log.info("需求规划 更新基础信息 日志记录");
                    }
                });
            } catch (Exception e) {
                log.error("需求规划 更新基础信息 日志记录异常", e);
            }
        }
        BusinessRequirementPlanBaseBean save = businessRequirementPlanBaseRepository.save(businessRequirementPlanBaseBean);
        if (Objects.nonNull(save)) {
            log.info("保存基础信息成功，baseId：{}", businessRequirementPlanBaseBean.getId());
        } else {
            throw new BusinessException("基础信息保存失败!");
        }

        return businessRequirementPlanBaseBean;
    }

    /*
     * @name:
     * @description: 保存或更新表和内容信息
     * @param RequirementPlanSaveReq
     * @date: 2020/12/19 下午4:00
     * @auther: zhy
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveTableAndForm(Long userId, Long baseId, Date planDate, List<RequirementPlanTableReq> requirementPlanTableReq, Long quantumArmyGroupId, String token) {
        List<BusinessRequirementPlanTableBean> businessRequirementPlanTableBeans = new ArrayList<>();
        List<BusinessRequirementPlanFormBean> businessRequirementPlanFormBeans = new ArrayList<>();
        List<BusinessRequirementPlanNeedBean> businessRequirementPlanNeedBeans = new ArrayList<>();

//        保存表信息
        for (RequirementPlanTableReq t :
                requirementPlanTableReq) {
            BusinessRequirementPlanTableBean businessRequirementPlanTableBean = businessRequirementPlanTableRepository.findByBaseIdAndProjectId(baseId, t.getProjectId());
            if (Objects.isNull(businessRequirementPlanTableBean)) {
//                    原来没有数据 新插入一条
                businessRequirementPlanTableBean = new BusinessRequirementPlanTableBean();
                Long tableId = SnowFlake.nextId();
                businessRequirementPlanTableBean.setId(tableId);
                businessRequirementPlanTableBean.setProjectId(t.getProjectId());
                businessRequirementPlanTableBean.setBaseId(baseId);
                businessRequirementPlanTableBean.setCreateUserId(userId);
                businessRequirementPlanTableBean.setTableDelete(0);
                // 保存操作记录
                try {
                    asyncTaskManager.getExecutor().submit(new Runnable() {
                        @Override
                        public void run() {
                            operationRecordService.addCreateAndDeleteLog(userId, quantumArmyGroupId, planDate, t, token);
                            log.info("需求规划 保存某个项目的表信息 日志记录");
                        }
                    });
                } catch (Exception e) {
                    log.error("需求规划 保存某个项目的表信息 日志记录异常", e);
                }

            } else {
                if (businessRequirementPlanTableBean.getTableDelete() == 1) {//原来的已经删除，算作新增数据记录
                    // 保存操作记录
                    try {
                        asyncTaskManager.getExecutor().submit(new Runnable() {
                            @Override
                            public void run() {
                                operationRecordService.addCreateAndDeleteLog(userId, quantumArmyGroupId, planDate, t, token);
                                log.info("需求规划 保存某个项目的表信息 日志记录");
                            }
                        });
                    } catch (Exception e) {
                        log.error("需求规划 保存某个项目的表信息 日志记录异常", e);
                    }
                }
                if (businessRequirementPlanTableBean.getTableDelete() == 0) { //原来数据没有删除，所有数据算作修改
                    // 保存操作记录
                    try {
                        List<BusinessRequirementPlanTableAndForm> businessRequirementPlanTableAndForms = businessRequirementPlanTableFormRepository.findByTableId(businessRequirementPlanTableBean.getId());
                        asyncTaskManager.getExecutor().submit(new Runnable() {
                            @Override
                            public void run() {
                                operationRecordService.updateCreateAndDeleteLog(userId, quantumArmyGroupId, planDate, businessRequirementPlanTableAndForms, t, token);
                                log.info("需求规划 修改某个项目的表信息 日志记录");
                            }
                        });
                    } catch (Exception e) {
                        log.error("需求规划 修改某个项目的表信息 日志记录异常", e);
                    }
                }
//                原来有数据，更新table记录
                businessRequirementPlanTableBean.setTableDelete(0);
                businessRequirementPlanTableBean.setUpdateUserId(userId);
//                删除表中的所有已配置的需求量和表内容
                List<BusinessRequirementPlanNeedBean> needs = businessRequirementPlanNeedRepository.findByTableIdAndNeedDelete(businessRequirementPlanTableBean.getId(), 0);
                List<BusinessRequirementPlanFormBean> forms = businessRequirementPlanFormRepository.findByTableIdAndFormDelete(businessRequirementPlanTableBean.getId(), 0);
                if (!CollectionUtils.isEmpty(needs)) {
                    needs.forEach(n -> {
                        n.setNeedDelete(1);
                        n.setUpdateUserId(userId);
                    });
                }
                if (!CollectionUtils.isEmpty(forms)) {
                    forms.forEach(f -> {
                        f.setFormDelete(1);
                        f.setUpdateUserId(userId);
                    });
                }
                businessRequirementPlanNeedRepository.save(needs);
                businessRequirementPlanFormRepository.save(forms);
                log.info("删除表中的所有已配置的需求量");
            }
            businessRequirementPlanTableBeans.add(businessRequirementPlanTableBean);

//            保存表内容信息
            for (RequirementPlanFormReq f :
                    t.getRequirementPlanFormRes()) {
                Long needId = SnowFlake.nextId();
                BusinessRequirementPlanNeedBean businessRequirementPlanNeedBean = new BusinessRequirementPlanNeedBean();

//                    新添加记录，查看之前是否有该项目、渠道、省份的接量存在
                List<String> provinceCode = Arrays.asList(f.getProvince().split(","));
                for (String p : provinceCode) {
                    BusinessRequirementPlanFormBean businessRequirementPlanFormBean = businessRequirementPlanFormRepository.findByTableIdAndChannelCodeAndProvince(businessRequirementPlanTableBean.getId(), f.getChannelCode(), p);
                    if (Objects.isNull(businessRequirementPlanFormBean)) {
                        businessRequirementPlanFormBean = new BusinessRequirementPlanFormBean();
                        // form信息不存在，新增加一条form记录
                        Long formId = SnowFlake.nextId();
                        businessRequirementPlanFormBean.setId(formId);
                        businessRequirementPlanFormBean.setTableId(businessRequirementPlanTableBean.getId());
                        businessRequirementPlanFormBean.setNeedId(needId);
                        businessRequirementPlanFormBean.setChannelCode(f.getChannelCode());
                        businessRequirementPlanFormBean.setProvince(p);
                        businessRequirementPlanFormBean.setAllotCount(0);
                        businessRequirementPlanFormBean.setCreateUserId(userId);
                        businessRequirementPlanFormBean.setFormDelete(0);
                    } else {
//                            form信息存在，更改记录状态和单元格信息
                        businessRequirementPlanFormBean.setFormDelete(0);
                        businessRequirementPlanFormBean.setNeedId(needId);
                    }
                    businessRequirementPlanFormBeans.add(businessRequirementPlanFormBean);
                }
                businessRequirementPlanNeedBean.setId(needId);
                businessRequirementPlanNeedBean.setTableId(businessRequirementPlanTableBean.getId());
                businessRequirementPlanNeedBean.setNeedCount(f.getNeedCount());
                businessRequirementPlanNeedBean.setNeedDelete(0);
                businessRequirementPlanNeedBean.setCreateUserId(userId);
                businessRequirementPlanNeedBeans.add(businessRequirementPlanNeedBean);
            }
        }
        businessRequirementPlanTableRepository.save(businessRequirementPlanTableBeans);
        log.info("保存表信息成功，表信息：{}", businessRequirementPlanTableBeans);
        businessRequirementPlanFormRepository.save(businessRequirementPlanFormBeans);
        log.info("保存内容信息成功,内容信息：{}", businessRequirementPlanFormBeans);
        businessRequirementPlanNeedRepository.save(businessRequirementPlanNeedBeans);
        log.info("保存需求量成功，需求量：{} ", businessRequirementPlanNeedBeans);
    }

    /*
     * @name:  queryRequirementPlanDistribution
     * @description: 查询机会分配的需求规划信息
     * @date: 2020/12/21
     * @auther: zhy
     *
     */
    public List<RequirementPlanDistributionRes> queryRequirementPlanDistribution(Long userId, Integer projectId, String channelCode, String province) {

        List<RequirementPlanDistributionRes> requirementPlanDistributionRes = new ArrayList<>();
//        根据用户id、项目、渠道、省份、合作状态 拿到与该用户合作的所有记录
        List<BusinessCooperativeBean> cooperativeBeans = cooperativeRepository.findByThrowUserIdAndProjectIdAndAdChannelCodeAndThrowProvinceCodeAndCooperativeState(userId, projectId, channelCode, province, 2);
        if (CollectionUtils.isEmpty(cooperativeBeans)) {
            return new ArrayList<>();
        }
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date planDate = null;
        try {
            String format = dateFormat.format(new Date());
            planDate = dateFormat.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date finalPlanDate = planDate;
        List<Long> qag = cooperativeBeans.stream()
                .map(BusinessCooperativeBean::getQuantumArmyGroupId)
                .collect(Collectors.toList());
        qag.stream()
                .distinct()
                .forEach(cb -> {
//                          根据量子军团id和日期拿到所有需求规划信息
                            List<RequirementPlanBaseTableForm> baseTableForms = businessRequirementPlanBaseTableFormRepository.findBaseTableForm(cb, finalPlanDate);
                            if (CollectionUtils.isEmpty(baseTableForms)) {
                                return;
                            }
                            RequirementPlanDistributionRes distributionRes = new RequirementPlanDistributionRes();
                            distributionRes.setQuantumArmyGroupId(baseTableForms.get(0).getQuantumArmyGroupId());
                            distributionRes.setCardCount(baseTableForms.get(0).getCardCount());
                            distributionRes.setEndTime(baseTableForms.get(0).getEndTime());
                            distributionRes.setPattern(baseTableForms.get(0).getPattern());
                            distributionRes.setReceivingResidue(baseTableForms.get(0).getReceivingResidue());
                            List<RequirementPlanContentRes> requirementPlanContentRes = new ArrayList<>();

//                          根据需求量id进行分组
                            Map<Long, List<RequirementPlanBaseTableForm>> mapTask = baseTableForms.stream().sorted(Comparator.comparing((b) -> b.getId())).collect(Collectors.groupingBy((a) -> a.getNeedId()));
                            for (Map.Entry<Long, List<RequirementPlanBaseTableForm>> entry : mapTask.entrySet()) {
                                List<String> provinces = new ArrayList<>();
                                Integer allotCount = 0;
                                for (RequirementPlanBaseTableForm p :
                                        entry.getValue()) {
//                                  获取省份code
                                    provinces.add(p.getProvince());
//                                  计算已分配量
                                    allotCount += p.getAllotCount();
                                }
                                RequirementPlanContentRes contentRes = new RequirementPlanContentRes();
                                BeanUtils.copyProperties(entry.getValue().get(0), contentRes);
                                contentRes.setAllotCount(allotCount);
                                contentRes.setProvince(String.join(",", provinces));
                                requirementPlanContentRes.add(contentRes);
                            }
                            distributionRes.setRequirementPlanContentRes(requirementPlanContentRes);
                            requirementPlanDistributionRes.add(distributionRes);
                        }
                );
        return requirementPlanDistributionRes;
    }

    /*
     * @name:  updateRequirementPlanDistribution
     * @description: 更新机会分配的需求规划信息
     * @date: 2020/12/25
     * @auther: zhy
     */
    public Boolean updateRequirementPlanDistribution(Integer quantumArmyGroupId, Integer projectId, String channelCode, String province, Integer allotCount) {

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date planDate = null;
        String format = "";
        try {
            format = dateFormat.format(new Date());
            planDate = dateFormat.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }

//        根据量子军团id、日期、项目id、渠道code、省份 查询列表内容信息
        BusinessRequirementPlanFormBean businessRequirementPlanFormBeans = businessRequirementPlanFormRepository.findByquantumArmyGroupIdAndPlanDateAndProjectIdAndProvince(quantumArmyGroupId, planDate, projectId, channelCode, province);

        if (Objects.isNull(businessRequirementPlanFormBeans)) {
            return false;
        }
        Integer newAllotCount = businessRequirementPlanFormBeans.getAllotCount() + allotCount;
//      删除redis中的信息
        if (redisTemplate.hasKey(RedisKeyConst.getRequirementPlan(quantumArmyGroupId, format))) {
            redisTemplate.delete(RedisKeyConst.getRequirementPlan(quantumArmyGroupId, format));
            log.info("更新机会分配 清除redis中的信息,量子军团={}，日期={}", quantumArmyGroupId, format);
        }
        businessRequirementPlanFormRepository.updateAllotCount(businessRequirementPlanFormBeans.getId(), newAllotCount);
        return true;
    }
}
